package com.db.mylogger;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class MyLogger {
	
	private PrintWriter writer;
	private File file;
	private BlockingQueue<String> msgQueue = new LinkedBlockingQueue<>();

	public MyLogger(String filename) throws IOException {
		file = new File(filename);
		if(!file.exists()) {
			file.createNewFile();
		}
		writer = new PrintWriter(filename);
		
		new Thread( new Runnable() {

			@Override
			public void run() {
				while(true) {
					String msg;
					try {
						msg = msgQueue.take();
						writer.println(msg);
						writer.flush();
					} catch (InterruptedException e) {
						System.out.println(msg(LogLevels.ERROR, "our writer thread was interrupted"));
						continue;
					} catch (RuntimeException e) {
						System.out.println(msg(LogLevels.ERROR, "our writer thread had died silently"));
						e.printStackTrace();
					}
				}
			}
		}).start();

	}
	
	public void info(String msg) {
		msgQueue.add(msg(LogLevels.INFO , msg));
	}
	
	public void info(String msg, Object o) {
		msgQueue.add(msg(LogLevels.INFO , msg, o));		
	}

	public void debug(String msg) {
		msgQueue.add(msg(LogLevels.DEBUG , msg));
	}
	
	public void debug(String msg, Object o) {
		msgQueue.add(msg(LogLevels.DEBUG , msg, o));
	}
	
	public void error(String msg) {
		msgQueue.add(msg(LogLevels.ERROR , msg));
	}
	
	public void error(String msg, Object o) {
		msgQueue.add(msg(LogLevels.ERROR , msg, o));
	}
	
	public String msg(LogLevels level, String msg) {
		return "[" + level + "] : " + new Date() + " : " + msg;
	}
	
	public String msg(LogLevels level, String msg, Object o) {
		return "[" + level + "] : " + new Date() + " : " + msg.replaceFirst("\\{\\}", o.toString());		
	}
	
}
